@file:Suppress("unused")

package com.virtualightning.mvvm.binding

import android.util.Log
import androidx.lifecycle.MutableLiveData
import kotlin.reflect.KProperty

/**
 *  Anchor : Create by CimZzz
 *  Time : 2021/12/27 15:49
 *  观察者 LiveData
 */
open class ObserverLiveData<T>: MutableLiveData<T>, SubjectCallback<T> {
	constructor() : super() {
		this.subjectType = -1
	}

	constructor(value: T) : super(value) {
		this.subjectType = -1
	}

	constructor(subjectType: Int, value: T) : super(value) {
		this.subjectType = subjectType
	}

	constructor(subjectType: Int) : super() {
		this.subjectType = subjectType
	}

	/**
	 * 观察主体类型键值
	 */
	val subjectType: Int

	/**
	 * 内部同步码
	 */
	private var syncCode: Int = -1

	/**
	 * 观察的主体
	 */
	private var subject: Subject<T>? = null

	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/12/27 3:53 下午 by CimZzz
	// 以下内容为:
	// 重写方法
	///////////////////////////////////////////////////////////////////////////

	/**
	 * Delegate Get 方法
	 * @param thisRef Any?
	 * @param property KProperty<*>
	 * @return T?
	 */
	operator fun getValue(thisRef: Any?, property: KProperty<*>): T? {
		return value
	}

	/**
	 * Delegate Set 方法
	 * @param thisRef Any?
	 * @param property KProperty<*>
	 * @param value T?
	 */
	operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
		this.value = value
		postValue(value)
	}

	/**
	 * 重写发送数据
	 * @param value T? 数据
	 */
	override fun postValue(value: T?) {
		// 发送数据
		val subject = this.subject
		if(subject != null) {
			// 如果存在观察主体，则会借由观察主体发送数据
			subject.postValue(value)
		} else {
			// 否则和一般 LiveData 一样
			super.postValue(value)
		}
	}


	/**
	 * Subject 数据变化
	 * @param syncCode Int 同步码
	 * @param value T? 变化的数据
	 */
	override fun onChanged(syncCode: Int, value: T?) {
		this.syncCode = syncCode
		super.postValue(value)
	}

	/**
	 * 获取当前观察回调的同步码
	 * @return Int 同步码
	 */
	override fun getSyncCode(): Int {
		return syncCode
	}


	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/12/27 3:50 下午 by CimZzz
	// 以下内容为:
	// 外部访问方法
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 分配一个观察主体
	 * @param subject Subject<T> 观察主体
	 * @param rewrite Boolean 是否重写数据
	 */
	internal fun assignSubject(subject: Subject<T>?, rewrite: Boolean) {
		if(subject != null) {
			this.subject = subject
			subject.observe(this)
			if(rewrite) {
				subject.postValue(value)
			}
		}
		else {
			detachSubject()
			this.subject = null
		}
	}

	/**
	 * 附着观察主体
	 */
	fun attachSubject() {
		subject?.observe(this)
	}

	/**
	 * 解绑观察主体
	 */
	fun detachSubject() {
		subject?.removeObserver(this)
	}

	/**
	 * 重写 toString 方法
	 * @return String toString
	 */
	override fun toString(): String {
		return value.toString()
	}
}